<template>
    <div class="w-2/3 h-2/3  m-auto" style="background-image: url(https://img0.baidu.com/it/u=651633018,343549103&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=600);
       ">
        <div class=" w-full h-full">
            <div class="h-full overflow-y-scroll overflow-x-hidden w-full "
                style="background-image: url(https://img0.baidu.com/it/u=651633018,343549103&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=600);">
                <div v-for="(message, index) in messages" :key="index" class="flex"
                    :class="{ 'justify-end': message.sender === 'me', 'justify-start': message.sender === 'other' }">
                    <span
                        :class="{ 'my-message ': message.sender === 'me', 'other-message': message.sender === 'other' }">{{
                            message.content }}</span>
                    <span v-if="message.sender === 'other'">
                        <el-icon class=" cursor-pointer text-xl text-blue-700">
                            <VideoPlay @click="playAudio(message.uid)" />

                        </el-icon>
                        <audio v-if="message.uid !== undefined" :src="'http://localhost:8000/file/' + message.uid + '.wav'"
                            :id="message.uid">{{
                                message.uid }}</audio>
                    </span>
                </div>
            </div>
            <div class=" w-full  mt-0  m-auto flex space-x-2 " style="height: 50px;">
                <div class="flex-1">
                    <el-input type="textarea" rows="4" placeholder="type your message" v-model="newMessage"></el-input>
                </div>
                <div>
                    <el-button @click="sendMessage" type="primary">发送</el-button>
                </div>
            </div>
        </div>

        <div class="fixed top-1/2 right-10 w">
            <el-card class="w-52">
                <template #header>
                    <div class="card-header text-center">
                        <span>语音识别</span>
                    </div>
                </template>
                <div class="flex justify-evenly">
                    <el-icon class=" cursor-pointer text-blue-500 " @click="startRecord">
                        <Microphone />
                    </el-icon>
                    <!-- <el-button @click="stopRecord">结束录音</el-button> -->
                    <el-icon class=" cursor-pointer text-red-400" @click="stopRecord">
                        <Mute />
                    </el-icon>
                </div>
            </el-card>
        </div>
        
        <div class="fixed top-1/3 left-10 ">
            <el-card class="w-52">
                <template #header>
                    <div class="card-header text-center">
                        <span>配置</span>
                    </div>
                </template>
                <div class="flex justify-evenly">
                    <div>
                        <span>对话方式</span>
                        <el-radio-group v-model="chatPattern" style="display: inline-block;">
                            <el-radio-button label="qa">检索</el-radio-button>
                            <el-radio-button label="bot">ChatBot</el-radio-button>
                        </el-radio-group>
                    </div>
                </div>
                <div>
                    <span>行为设置</span>
                    <el-checkbox-group v-model="checked" style="display: inline-block;">
                        <el-checkbox label="1">自动发送</el-checkbox>
                        <el-checkbox label="2">自动转化</el-checkbox>
                    </el-checkbox-group>
                </div>
            </el-card>
        </div>

    </div>
</template>

<script setup>
import Recorder from 'js-audio-recorder';
import { ElMessage, ElLoading, ElNotification } from "element-plus";
import { h, ref, nextTick } from 'vue'
import { api } from '../boot/api'
let chatPattern = ref('bot')
let checked = ref([])
const scrollToBottom = () => {
    nextTick(() => {
        let container = document.querySelector('.overflow-y-scroll');
        container.scrollTop = container.scrollHeight;
    })
}

nextTick(() => {
    scrollToBottom()

})

let messages = ref([
])
let newMessage = ref('');
let currentUser = ref('me') // 当前用户，可设为 'me' 或 'other'
const queryDialog = () => {
    let user_inputs = []
    let ai_outputs = []
    messages.value.forEach(item => {
        if (item.sender === 'me') {
            user_inputs.push(item.content)
        } else {
            ai_outputs.push(item.content)
        }
    })
    return { 'user_inputs': user_inputs, 'ai': ai_outputs }
}
const playAudio = (tagId) => {
    let dom = document.getElementById(tagId)
    if (dom !== null) {
        if (dom.paused) {
            dom.play()
        } else {
            dom.pause()
        }
    }
    scrollToBottom()

}
let sendMessage = () => {
    //清空音频
    audios.value = []

    let historyDialog = queryDialog();
    

    if (newMessage.value) {
        messages.value.push({
            sender: currentUser.value,
            content: newMessage.value,
        });
        scrollToBottom()
        api({
            url: 'chat',
            method: 'post',
            data: {
                'past_user_input': historyDialog.user_inputs,
                'generated_responses': historyDialog.ai,
                'text': newMessage.value,
                'pattern': chatPattern.value
            }
        }).then(res => {
            let response = res.data
            let data = response.data

            api({
                url: 'text_to_speech',
                method: 'post',
                data: {
                    'text': data
                }
            }).then(res => {
                let uid = res.data.file
                messages.value.push({
                    'sender': 'other', 'content': data, 'uid': uid
                })

                nextTick(() => {
                    playAudio(uid)
                })
            })
        })
        newMessage.value = '';
    }
}

let recorder = new Recorder(
    {
        sampleBits: 16,                 // 采样位数，支持 8 或 16，默认是16
        sampleRate: 16000,              // 采样率，支持 11025、16000、22050、24000、44100、48000，根据浏览器默认值，我的chrome是48000
        numChannels: 1,
    }
);
let audios = ref([])
let duration = ref(0)
let blobData = ref()
let totalDuration = ref(0)
const openNotification = () => {
    // read blob data from url 
    ElNotification({
        title: '音频',
        message: h('div',
            {
                class: 'w-52 h-full'
            },
            [
                h(
                    'audio', {
                    src: audios.value.map(elm => elm.url),
                    class: 'w-52 h-8',
                    controls: 'controls',
                }
                ),
                h('button',
                    {
                        type: 'button',
                        class: 'text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 mr-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800',
                        onClick: () => {

                            let formData = new FormData();
                            formData.append('data', blobData.value);
                            ElLoading.service({
                                lock: true,
                                text: '正在识别中...初始化时间较长，请耐心等待',
                                background: 'rgba(0, 0, 0, 0.7)'
                            });
                            // colse notification
                            ElNotification.closeAll()
                            api({
                                url: 'speech_to_text',
                                method: 'post',
                                data: formData
                            }).then(res => {
                                console.log(res)
                                let response = res.data
                                let text = response.text
                                newMessage.value = text
                                ElLoading.service().close()
                            }).then(()=>{
                                if(checked.value.includes('1')){
                                   sendMessage()
                                }
                            })
                        }
                    },
                    '确认')
            ]

        ),
        duration: 0
    })
}
const startRecord = () => {
    recorder.start().then(() => {
        console.log('开始录音');
        ElMessage.success('开始录音')
    }).catch((e) => {
        console.error(e);
    });
}
const stopRecord = () => {
    recorder.stop()
    totalDuration.value = recorder.duration
    let blob = recorder.getWAVBlob();
    blobData.value = blob
    audios.value.push({
        name: '音频1',
        url: URL.createObjectURL(blob)
    })
    ElMessage.success('结束录音')
    openNotification()
    console.log(checked.value)
    if (checked.value.includes('2')){
        
        let formData = new FormData();
        formData.append('data', blobData.value);
        ElLoading.service({
            lock: true,
            text: '正在识别中...初始化时间较长，请耐心等待',
            background: 'rgba(0, 0, 0, 0.7)'
        });
        // colse notification
        ElNotification.closeAll()
        api({
            url: 'speech_to_text',
            method: 'post',
            data: formData
        }).then(res => {
            console.log(res)
            let response = res.data
            let text = response.text
            newMessage.value = text
            ElLoading.service().close()
        }).then(()=>{
            if(checked.value.includes('1')){
                sendMessage()
            }
        })
    }
    
}
const playRecord = () => {
    let blob = recorder.getPCMBlob();

    duration.value = 0;
    let id = setInterval(() => {
        duration.value = duration.value + 1;
    }, 1000)
    window.setTimeout(function () {
        window.clearInterval(id);
    }, recorder.duration * 1000);
    recorder.play(blob);
}
const destory = () => {
    recorder.destroy();
    duration.value = 0;
    totalDuration.value = 0;
    audios.value = []
}



</script>

<style>
.chat-container {
    display: flex;
    flex-direction: column;
    height: 80vh;
}

.chat-messages {
    flex-grow: 1;
    overflow-y: auto;
}

.my-message {
    align-self: flex-end;
    justify-content: flex-end;
    background-color: #dcf8c6;
    color: #333;
    padding: 10px;
    margin: 10px;
    border-radius: 8px;
}

.other-message {
    align-self: flex-start;
    background-color: #f5f5f5;
    color: #333;
    padding: 10px;
    margin: 10px;
    border-radius: 8px;
}

.chat-input {}

input[type="text"] {
    flex-grow: 1;
    padding: 5px;
    margin-right: 10px;
}

button {
    padding: 5px 10px;
}
</style>
